package com.log320.huffman;

import java.util.LinkedList;
//This class represent a code in binary characters. It contains a list of boolean
//values representing zeros and ones and an associated character (that this binary code represents
//in our huffman encoding)
public class BinaryCode implements Comparable<BinaryCode>{
	
	private LinkedList<Boolean> binaryCodeList;
	private int character;
	private int desiredCodeLength = -1; // used to reconstruct huffman tree from canonical header (-1 mean it has not been initialised/meant to be used)
	
	public int getCharacter() {
		return character;
	}
	
	public LinkedList<Boolean> getBinaryCodeListClone(){
		return (LinkedList<Boolean>) binaryCodeList.clone();
	}

	public int getDesiredCodeLength() {
		return desiredCodeLength;
	}

	public BinaryCode(int character){
		this.character = character;
		binaryCodeList = new LinkedList<Boolean>();
	}
	
	public BinaryCode(int character, int desiredCodeLength){
		this.character = character;
		this.desiredCodeLength = desiredCodeLength;
		binaryCodeList = new LinkedList<Boolean>();
	}
	
	public BinaryCode(int character, LinkedList<Boolean> binaryCodeList){
		this.character = character;
		this.binaryCodeList = binaryCodeList;
	}
	
	public void addBit(boolean bit){
		binaryCodeList.add(bit);
	}
	
	public int size(){
		int value;
		if (desiredCodeLength != -1)
			value = desiredCodeLength;
		else
			value = binaryCodeList.size();
		return value;
	}
	
	public boolean get(int pos){
		return binaryCodeList.get(pos);
	}
	
	public void setToBit(int value){
		setToBit(value, size());
	}
	
	public void setToBit(int value, int size){
		LinkedList<Boolean> binCodeList = new LinkedList<Boolean>();
		for (int i = size; i >= 1; i--){
			binCodeList.add(((value >> (i-1)) & 1) == 1);
		}
		binaryCodeList = binCodeList;
	}

	//Comparator for binary code. First compare by number of binary values,
	//then by character ascii order
	@Override
	public int compareTo(BinaryCode comparedBinaryCode) {
		int value;
		if(this.binaryCodeList.size() < comparedBinaryCode.binaryCodeList.size()){
			value = -1;
		}else if (this.binaryCodeList.size() > comparedBinaryCode.binaryCodeList.size()){
			value = 1;
		}else{
			//Compare by character
			if(this.character < comparedBinaryCode.character){
				value = -1;
			}else{
				value = 1;
			}
		}
		return value;
	}
	
	

}
